#include "../inc/skyTreeNode.h"
namespace Sky
{
	TreeNode::TreeNode(TUint id):
m_FirstChild(vNull),
m_LastChild(vNull),
m_Prev(vNull),
m_Next(vNull),
m_Parent(vNull),
m_Id(id)
{

}

TreeNode::TreeNode():
m_FirstChild(vNull),
m_LastChild(vNull),
m_Prev(vNull),
m_Next(vNull),
m_Parent(vNull),
m_Id(0)
{

}

TreeNode* TreeNode::getParent()
{
	return this->m_Parent;
}

TreeNode* TreeNode::getFirstChild()
{
	return this->m_FirstChild;
}

TreeNode* TreeNode::getLastChild()
{
	return this->m_LastChild;
}

TreeNode* TreeNode::getNextSibling()
{
	return this->m_Next;
}

TreeNode* TreeNode::getPrevSibling()
{
	return this->m_Prev;
}

TreeNode* TreeNode::getNext()
{

	TreeNode* pTmpNode;

	if (this->m_FirstChild)
		return this->m_FirstChild;

	if (this->m_Next)
		return this->m_Next;

	pTmpNode = this->m_Parent;
	while (pTmpNode) {
		if (pTmpNode->m_Next)
			return pTmpNode->m_Next;

		pTmpNode = pTmpNode->m_Parent;
	}
	return vNull;

}

TreeNode* TreeNode::getPrev()
{
	TreeNode* pTmpNode;
	if (this->m_Prev) {
		pTmpNode = this->m_Prev;
		while (pTmpNode->m_LastChild) {
			pTmpNode = pTmpNode->m_LastChild;	
		}		
		return pTmpNode;
	} else {
		return this->m_Parent;
	}
}

TreeNode* TreeNode::getNext_OverChild()
{
	TreeNode* pTmpNode;


	if (this->m_Next)
		return this->m_Next;

	pTmpNode = this->m_Parent;
	while (pTmpNode) {
		if (pTmpNode->m_Next)
			return pTmpNode->m_Next;

		pTmpNode = pTmpNode->m_Parent;
	}
	return vNull;
}

TreeNode* TreeNode::getNext_InSubTree( TreeNode* node )
{
	TreeNode* pTmpNode;

	if (this->m_FirstChild)
		return this->m_FirstChild;

	if (this->m_Next)
		return this->m_Next;

	pTmpNode = this->m_Parent;
	while (pTmpNode) {
		if (pTmpNode->m_Next)
			return pTmpNode->m_Next;
		else if(pTmpNode->m_Parent == node)
			return vNull;

		pTmpNode = pTmpNode->m_Parent;
	}
	return vNull;
}

TreeNode* TreeNode::getPrev_InSubTree( TreeNode* node )
{
	TreeNode* pTmpNode;
	if (this->m_Prev) {
		pTmpNode = this->m_Prev;
		while (pTmpNode->m_LastChild) {
			pTmpNode = pTmpNode->m_LastChild;	
		}		
		return pTmpNode;
	} else {
		if(this->m_Parent == node)
			return vNull;
		return this->m_Parent;
	}
}
TBool TreeNode::attachFirstChild( TreeNode* child )
{
	child->m_Parent = this;
	child->m_Next = this->m_FirstChild;
	if(this->m_FirstChild)
		this->m_FirstChild->m_Prev = (TreeNode*)child;
	this->m_FirstChild = child;
	if(this->m_LastChild == vNull)
		this->m_LastChild = child;
	return vTrue;
}

TBool TreeNode::attachLastChild( TreeNode* child )
{
	child->m_Parent = this;
	child->m_Prev = this->m_LastChild;
	if(this->m_LastChild)
		this->m_LastChild->m_Next = (TreeNode*)child;
	this->m_LastChild = child;
	if(this->m_FirstChild == vNull)
		this->m_FirstChild = child;
	return vTrue;
}

TBool TreeNode::attachNextSibling( TreeNode* sibling )
{
	sibling->m_Parent = this->m_Parent;
	if(this->m_Next)
		this->m_Next->m_Prev = (TreeNode*)sibling;
	sibling->m_Next = this->m_Next;
	sibling->m_Prev = this;
	this->m_Next = sibling;
	if(this->m_Parent)
	{
		if(this->m_Parent->m_LastChild =(TreeNode*) this)
			this->m_Parent->m_LastChild =(TreeNode*) sibling;
	}
	return vTrue;
}

TBool TreeNode::attachPrveSibling( TreeNode* sibling )
{
	sibling->m_Parent = this->m_Parent;
	if(this->m_Prev)
		this->m_Prev->m_Next = sibling;
	sibling->m_Next = this;
	sibling->m_Prev = this->m_Prev;
	if(this->m_Parent)
	{
		if(this->m_Parent->m_FirstChild = this)
			this->m_Parent->m_FirstChild = sibling;
	}
	return vTrue;

}

TreeNode* TreeNode::detachFirstChild()
{
	TreeNode* node = vNull;
	if(this->m_FirstChild)
	{
		node = (TreeNode*)this->m_FirstChild;
		this->m_FirstChild = node->m_Next;
		node->m_Parent = vNull;
		node->m_Next = vNull;

		if(this->m_LastChild == node)
			this->m_LastChild = vNull;
	}
	if(this->m_FirstChild)
		this->m_FirstChild->m_Prev = vNull;
	return node;
}

TreeNode* TreeNode::detachLastChild()
{
	TreeNode* node = vNull;
	if(this->m_LastChild)
	{
		node = (TreeNode*)this->m_LastChild;
		this->m_LastChild = node->m_Prev;
		node->m_Parent = vNull;
		node->m_Next = vNull;

		if(this->m_FirstChild == node)
			this->m_FirstChild = vNull;
	}
	if(this->m_LastChild)
		this->m_LastChild->m_Next = vNull;
	return node;
}

TreeNode* TreeNode::detachNextSibling()
{
	TreeNode* node = vNull;
	if(this->m_Next)
	{
		node = (TreeNode*)this->m_Next;
		this->m_Next = node->m_Next;
		node->m_Parent = vNull;
		node->m_Prev = vNull;
		node->m_Next = vNull;
	}
	if(this->m_Next)
		this->m_Next->m_Prev = this;
	return node;
}

TreeNode* TreeNode::detachPrevSibling()
{
	TreeNode* node = vNull;
	if(this->m_Prev)
	{
		node = (TreeNode*)this->m_Prev;
		this->m_Prev = node->m_Prev;
		node->m_Parent = vNull;
		node->m_Prev = vNull;
		node->m_Next = vNull;
	}
	if(this->m_Prev)
		this->m_Prev->m_Next = this;
	return node;
}

TreeNode* TreeNode::detachCurrent()
{
	TreeNode* parent;

	parent = (TreeNode*)this->m_Parent;
	if(parent)
	{
		if(parent->m_FirstChild == this)
			parent->m_FirstChild = this->m_Next;
		if(parent->m_LastChild == this)
			parent->m_LastChild = this->m_Prev;
		this->m_Parent = vNull;
	}

	if(this->m_Prev)
	{
		this->m_Prev->m_Next = this->m_Next;
		this->m_Prev = vNull;
	}

	if(this->m_Next)
	{
		this->m_Next->m_Prev = this->m_Prev;
		this->m_Parent = vNull;
	}
	return this;
}

TreeNode* TreeNode::detachAllChildren()
{
	TreeNode* n = this->m_FirstChild;
	this->m_FirstChild = vNull;
	this->m_LastChild = vNull;
	TreeNode* temp = n;
	while(temp)
	{
		temp->m_Parent = vNull;
		temp =  temp->m_Next;
	}
	return n;
}

TreeNode* TreeNode::exchangeCurrent( TreeNode* node )
{
	if(node)
	{
		//parent node adjust
		TreeNode* thisTemp;
		TreeNode* thatTemp;

		thisTemp = this->m_Parent;
		thatTemp = node->m_Parent;

		node->m_Parent = thisTemp;
		this->m_Parent = thatTemp;

		if(thisTemp)
		{
			if(thisTemp->m_FirstChild == this)
				thisTemp->m_FirstChild = node;
			if(thisTemp->m_LastChild == this)
				thisTemp->m_LastChild = node;
			this->m_Parent = thatTemp;
		}
		if(thatTemp)
		{
			if(thatTemp->m_FirstChild == node)
				thatTemp->m_FirstChild = this;
			if(thatTemp->m_LastChild == node)
				thatTemp->m_LastChild = this;
			node->m_Parent = thisTemp;
		}
		//
		thisTemp = this->m_Prev;
		thatTemp = node->m_Prev;

		node->m_Prev = thisTemp;
		if(thisTemp)
		{
			thisTemp->m_Next = node;
		}
		this->m_Prev = thatTemp;
		if(thatTemp)
		{
			thatTemp->m_Next = this;
		}

		thisTemp = this->m_Next;
		thatTemp = node->m_Next;

		node->m_Next = thisTemp;
		if(thisTemp)
		{
			thisTemp->m_Prev = node;
		}
		this->m_Next = thatTemp;
		if(thatTemp)
		{
			thatTemp->m_Prev = this;
		}
		return this;
	}
	else
	{
		return detachCurrent();
	}
	return vNull;	
}

TreeNode* TreeNode::detachColne()
{
	m_Prev = vNull;
	m_Next = vNull;
	m_Parent = vNull;
	m_FirstChild = vNull;
	m_LastChild = vNull;
	return this;
}

#ifdef MY_CHECK
#define CheckNode(n,ret)	do{if(!isBelongTree(n)){myWarning("node is not belong to tree");return ret;}}while(0)
#else
#define CheckNode(n,ret)	 
#endif

TreeNode* TreeManager::getParentLastTraverseOf( TreeNode* node )
{
	return vNull;
}

TBool TreeManager::attachLastChildOf( TreeNode* node,TreeNode* child )
{
	if(vNull == node)
	{
		m_Root = child;
		return vTrue;
	}
	CheckNode(node,vFalse);
	return node->attachLastChild(child);
}

TBool TreeManager::attachFirstChildOf( TreeNode* node,TreeNode* child )
{
	if(vNull == node)
	{
		m_Root = child;
		return vTrue;
	}
	CheckNode(node,vFalse);
	return node->attachFirstChild(child);
}

TBool TreeManager::attachNextSiblingOf( TreeNode* node,TreeNode* sibling )
{
	if(vNull == node)
	{
		m_Root = sibling;
		return vTrue;
	}
	CheckNode(node,vFalse);
	return node->attachNextSibling(sibling);
}

TBool TreeManager::attachPrevSiblingOf( TreeNode* node,TreeNode* sibling )
{
	if(vNull == node)
	{
		m_Root = sibling;
		return vTrue;
	}
	CheckNode(node,vFalse);
	return node->attachPrveSibling(sibling);
}

TreeNode* TreeManager::detachLastChildOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachLastChild();
}

TreeNode* TreeManager::detachFirstChildOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachFirstChild();
}

TreeNode* TreeManager::detachPrevSiblingOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachPrevSibling();
}

TreeNode* TreeManager::detachAllChildrenOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachAllChildren();
}

TreeNode* TreeManager::detach( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachCurrent();
}

TreeNode* TreeManager::detachNextSiblingOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->detachNextSibling();
}

TreeNode* TreeManager::exchange( TreeNode* thisNode,TreeNode* thatNode )
{
	CheckNode(thisNode,vNull);
	return thisNode->exchangeCurrent(thatNode);
}

TreeNode* TreeManager::getParentOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getParent();
}

TreeNode* TreeManager::getLastChildOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getLastChild();
}

TreeNode* TreeManager::getFirstChildOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getFirstChild();
}

TreeNode* TreeManager::getPrevSiblingOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getPrevSibling();
}

TreeNode* TreeManager::getNextSiblingOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getNextSibling();
}

TreeNode* TreeManager::getParentFirsTraverseOf( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getNext_InSubTree(m_Root);
}


TreeNode* TreeManager::getParentFirsTraverseOf_Reverse( TreeNode* node )
{
	CheckNode(node,vNull);
	return node->getPrev_InSubTree(m_Root);
}

TreeNode* TreeManager::getSubTreeParentFirsTraverseOf( TreeNode* node,TreeNode* subRoot )
{
	CheckNode(node,vNull);
	CheckNode(subRoot,vNull);
	return node->getNext_InSubTree(subRoot);
}

TreeNode* TreeManager::getTreeNode( TUint id )
{
	TreeNode* ctl = m_Root;
	while(ctl)
	{
		if(ctl->m_Id == id)
			return ctl;
		else
			ctl = ctl->getNext();
	}
	return vNull;
}

TBool TreeManager::setRoot( TreeNode* root )
{
	m_Root = root;
	return vTrue;
}

TBool TreeManager::isBelongTree( TreeNode* node )
{
	xAssert(node);
	do
	{
		if(node == m_Root)
			return vTrue;
	}while(node = node->m_Parent);

	return vFalse;
}


}